/*-
 * Copyright (c) 2006 Vishal Patil <bsd.devil@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#ifndef _ISCSI_SESSION_
#define _ISCSI_SESSION_

#include "iscsi_pdu.h"

#define ISCSI_ISID_LENGTH	6

/* Used to defined the login states */
typedef enum {
	ISCSI_SECNEGO_STATE,
	ISCSI_OPNEGO_STATE,
	ISCSI_FULL_FEATURED_STATE
}login_state_t;

/* Used to define the connection states */
typedef enum {
	ISCSI_CONN_FREE,			/* S1 */
        ISCSI_CONN_XPT_WAIT,			/* S2 */
	ISCSI_CONN_LOGGING_IN,			/* S4 */
	ISCSI_CONN_LOGGED_IN,			/* S5 */
	ISCSI_CONN_LOGGING_OUT,			/* S6 */
	ISCSI_CONN_LOGOUT_REQUESTED,		/* S7 */
	ISCSI_CONN_CLEANUP_WAIT			/* S8 */	
} conn_state_t;

/* A structure used for iSCSI connection */
struct iscsi_conn {
	/* Pointer to the next connection in an iSCSI session */
	struct iscsi_conn * next;
	/* Socket bearing the connection */
	int sock;
	/* Connection id */
	uint32_t cid;
	/* Login state */
	login_state_t login_state;
	/* Connection state*/
        conn_state_t conn_state;
	/* expected status sn */
	uint32_t expstatsn;
	/* Last status sn*/
	uint32_t laststatsn;	
};


typedef enum {
	ISCSI_SESS_FREE,		/* Q1 */
	ISCSI_SESS_LOGGED_IN,		/* Q3 */
	ISCSI_SESS_FAILED		/* Q4 */
} sess_state_t;

struct iscsi_session {

	/* Target name */	
	char tname[ISCSI_MAX_NAME_LEN]; 

	/* Target port */
	int port;
		
	/* Used to store the state of the iSCSI session */
	sess_state_t state;

	/* Points to the list of connections for the session */
	struct iscsi_conn * conn_head;

	/* Used to store the currently active connection */
	struct iscsi_conn * active_conn;

	/* Used to store the next connection id*/
	uint32_t next_cid;

	/* Used to store the next Initiator Task Tag */
	uint32_t next_itt;

	/* Used to store the iSCSI session id*/
	uint8_t isid[ISCSI_ISID_LENGTH];

	/* Used to store the login params */
	struct iscsi_login_params * login_params;

	/* Used to store the next CmdSN - Set by the initiator */
	uint32_t cmdsn;

	/* Used to store the ExpCmdSN - Provided by the target */
	uint32_t expcmdsn;

	/* Used to store the MaxCmdSN - Provided by the target */
	uint32_t maxcmdsn;
};

extern int
iscsi_session_init(struct iscsi_session * sess);

extern int
iscsi_session_add_conn(struct iscsi_session * sess, 
			struct iscsi_conn * conn);
#endif
